package mt.dummy;



import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import mt.Order;
import mt.client.MicroTrader;
import mt.comm.ClientComm;
import mt.comm.ClientSideMessage;
import mt.comm.ServerSideMessage;
import mt.dummy.ClientMessage;
import mt.dummy.ServerMessage;

/**
 * ClientCommDummy is used by the GUI of the client to communicate with the
 * server.
 * 
 * @author Pedro,Rita,Miguel
 * 
 */
public class ClientCommDummy implements ClientComm {

	// private Socket socket;

	// private ObjectOutputStream out;
	// private ObjectInputStream in;
	private BlockingQueue<ClientMessage> q = new ArrayBlockingQueue<ClientMessage>(
			100);
	private String nickname;
	private boolean isConnected = false;
	InetAddress host;
	Socket socket = null;
	ObjectOutputStream oos = null;
	ObjectInputStream ois = null;
	MicroTrader window;

	public synchronized ObjectOutputStream getoos() {
		return this.oos;
	}

	public synchronized ObjectInputStream getois() {
		return this.ois;
	}

	public void connect(String serverAddress, String nickname, MicroTrader _window) throws UnknownHostException,	ClassNotFoundException, IOException, InterruptedException {
		this.window = _window;
		connect(serverAddress, nickname);

	}
	Receive reciever;
	@Override
	public void connect(String serverAddress, String nickname)
			throws UnknownHostException, IOException, ClassNotFoundException,
			InterruptedException {

		// get the localhost IP address, if server is running on some other IP,
		// you need to use that
		host = InetAddress.getLocalHost();
		// for(int i=0; i<5;i++){
		// establish socket connection to server
		socket = new Socket(host.getHostName(), 9870);
		// write to socket using ObjectOutputStream
		oos = new ObjectOutputStream(socket.getOutputStream());
		ois = new ObjectInputStream(socket.getInputStream());

		System.out.println("Sending request to Socket Server");
		ServerMessage message = new ServerMessage(
				ServerSideMessage.Type.CONNECTED, nickname, null);

		getoos().writeObject(message);

		 reciever = new Receive(getois(), getoos());
		reciever.start();
		//
		//
		// if (ois.readObject() != null) {
		// ClientMessage clientMessage = (ClientMessage) ois.readObject();
		// window.updateUnfulfilledTable(clientMessage.getOrder());
		// System.out.println("Message: ");
		// }
		//

	}

	/**
	 * This Threads receives and processed the ClientMessage.
	 */
	class Receive extends Thread {

		private ObjectInputStream in;
		private ObjectOutputStream out;

		public Receive(ObjectInputStream _in,ObjectOutputStream _out) {
			in = _in;
			out =_out;
		}

		@Override
		public void run() {
			try {
				while (true) {
					ClientMessage msg = (ClientMessage) getoins().readObject();
					// q.add(msg);
					window.updateUnfulfilledTable(msg.getOrder());
					System.out.println("I recieved a message");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		public void sendMessage(ServerMessage obj){
			try {
				out.writeObject(obj);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		public synchronized ObjectInputStream getoins() {
			return this.in;
		}
	}

	@Override
	public boolean isConnected() {
		return isConnected;
	}

	@Override
	public void disconnect() {
		// TODO Auto-generated method stub
		try {
			isConnected = false;
			ois.close();
			oos.close();
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public boolean hasNextMessage() {
		// TODO Auto-generated method stub
		return !q.isEmpty();
	}

	@Override
	public ClientSideMessage getNextMessage() {
		// TODO Auto-generated method stub
		return q.poll();
	}

	@Override
	public void sendOrder(Order order) {
		try {
			//
			// oos = new ObjectOutputStream(socket.getOutputStream());
//			getoos().writeObject((Object) (new ServerMessage(
//					ServerSideMessage.Type.NEW_ORDER, order.getNickname(),
//					order)));
//			 oos.flush();
//			//
//			// ois = new ObjectInputStream(socket.getInputStream());
//			 //ObjectInputStream s = getois();
//			 Object clientMessage;
//			if ((clientMessage = (Object) getois().readObject()) != null) {
//				System.out.println("Cheguei Aqui");
//				 //= (ClientMessage) getois().readObject();
//				//window.updateUnfulfilledTable(clientMessage.getOrder());
//				System.out.println("Message: ");
//				System.out.println(clientMessage);
//			}
			reciever.sendMessage((new ServerMessage(ServerSideMessage.Type.NEW_ORDER, order.getNickname(),order)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
